package de.dhbw.minf12.mas;

import static org.junit.Assert.*;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import org.junit.Before;
import org.junit.Test;

import de.dhbw.minf12.mas.logic.AbstractTargetFunctionLogic;
import de.dhbw.minf12.mas.logic.SupplierLogic;
import de.dhbw.minf12.mas.voter.ApprovalVoter;

/**
 * Test Case für den ApprovalVoter
 * @author flo
 *
 */
public class ApprovalVoterTester {
	private static int CONTRACT_LIST_SIZE = 5;
	
	private ApprovalVoter supplierApprovalVoter;
	
	@Before
	public void setUp() throws Exception {
		int[][] t  = FileImporter.loadInstanceFile("input/beispiel");
		AbstractTargetFunctionLogic targetFunction = new SupplierLogic(t);
		supplierApprovalVoter = new ApprovalVoter(targetFunction);
	}

	@Test
	public void testVote() {
		List<Permutation> contracts = this.generateContracts();
		
		//Aktueller Contract: Wert 9 (schlechtester)
		//minApprovalCount: 5 (= Größe gesamte Contract Liste)
		//Erwartetes Resultat: Ursprungs-Contract-Liste, nach Value sortiert
		List<Integer> data = new LinkedList<Integer>();
		data.add(2); data.add(0); data.add(1);
		Permutation currentContract = new Permutation(data);
		List<Permutation> votedContracts = supplierApprovalVoter.vote(contracts, currentContract, CONTRACT_LIST_SIZE);
		
		assertNotNull(votedContracts);
		assertEquals(CONTRACT_LIST_SIZE, votedContracts.size());
		assertEquals(contracts.get(2), votedContracts.get(0));
		assertEquals(contracts.get(0), votedContracts.get(1));
		assertEquals(contracts.get(3), votedContracts.get(2));
		assertEquals(contracts.get(1), votedContracts.get(3));
		assertEquals(contracts.get(4), votedContracts.get(4));
		
		
		//Aktueller Contract: Wert 8
		//minApprovalCount: 3
		//Erwartetes Resultat: Alle Contracts außer schlechtestem 
		data = new LinkedList<Integer>();
		data.add(0); data.add(2); data.add(1);
		currentContract = new Permutation(data);
		votedContracts = supplierApprovalVoter.vote(contracts, currentContract, 3);
		
		assertNotNull(votedContracts);
		assertEquals(4, votedContracts.size());
		assertEquals(contracts.get(2), votedContracts.get(0));
		assertEquals(contracts.get(0), votedContracts.get(1));
		assertEquals(contracts.get(3), votedContracts.get(2));
		assertEquals(contracts.get(1), votedContracts.get(3));
		
		
		//Aktueller Contract: Wert 6
		//minApprovalCount: 1
		//Erwartetes Resultat: Contracts mit Wert 4, 5, 6
		data = new LinkedList<Integer>();
		data.add(1); data.add(2); data.add(0);
		currentContract = new Permutation(data);
		votedContracts = supplierApprovalVoter.vote(contracts, currentContract, 1);
		
		assertNotNull(votedContracts);
		assertEquals(3, votedContracts.size());
		assertEquals(contracts.get(2), votedContracts.get(0));
		assertEquals(contracts.get(0), votedContracts.get(1));
		assertEquals(contracts.get(3), votedContracts.get(2));
		
		
		//Aktueller Contract: Wert 6
		//minApprovalCount: 4
		//Erwartetes Resultat: Contracts mit Wert 4, 5, 6
		data = new LinkedList<Integer>();
		data.add(1); data.add(2); data.add(0);
		currentContract = new Permutation(data);
		votedContracts = supplierApprovalVoter.vote(contracts, currentContract, 4);
		
		assertNotNull(votedContracts);
		assertEquals(4, votedContracts.size());
		assertEquals(contracts.get(2), votedContracts.get(0));
		assertEquals(contracts.get(0), votedContracts.get(1));
		assertEquals(contracts.get(3), votedContracts.get(2));
		assertEquals(contracts.get(1), votedContracts.get(3));
		
	}

	private List<Permutation> generateContracts() {
		List<Permutation> contracts = new ArrayList<Permutation>(CONTRACT_LIST_SIZE);
		
		//Wert 5
		List<Integer> data = new LinkedList<Integer>();
		data.add(0); data.add(1); data.add(2);
		contracts.add(new Permutation(data));
		
		//Wert 8
		data = new LinkedList<Integer>();
		data.add(0); data.add(2); data.add(1);
		contracts.add(new Permutation(data));
		
		//Wert 4
		data = new LinkedList<Integer>();
		data.add(1); data.add(0); data.add(2);
		contracts.add(new Permutation(data));
		
		//Wert 6
		data = new LinkedList<Integer>();
		data.add(1); data.add(2); data.add(0);
		contracts.add(new Permutation(data));
		
		//Wert 9
		data = new LinkedList<Integer>();
		data.add(2); data.add(0); data.add(1);
		contracts.add(new Permutation(data));
		
		return contracts;
	}

}
